#ifndef CALENDARWIDGET_H
#define CALENDARWIDGET_H

#include <QtGui>
#include <QtSql>

#include "optiondialog.h"
#include "coreutils.h"
#include "eventhint.h"

namespace Ui {
    class CalendarWidget;
}

class CalendarModel;
class CalendarView;
class CalendarDelegate;
class MenuButton;
class EventHint;

class CalendarWidget : public QWidget
{
    Q_OBJECT
public:
    enum HorizontalHeaderFormat {
        NoHorizontalHeader,
        SingleLetterDayNames,
        ShortDayNames,
        LongDayNames
    };

    enum SelectionMode {
        NoSelection,
        SingleSelection
    };

    static void run(QWidget *parent = 0);

    virtual QSize sizeHint() const;
    virtual QSize minimumSizeHint() const;

    QDate selectedDate() const;

    int yearShown() const;
    int monthShown() const;

    QDate minimumDate() const;
    void setMinimumDate(const QDate &date);
    QDate maximumDate() const;
    void setMaximumDate(const QDate &date);

    Qt::DayOfWeek firstDayOfWeek() const;
    void setFirstDayOfWeek(Qt::DayOfWeek dayOfWeek);

    bool isGridVisible() const;
    bool isNavigationBarVisible() const { return navBarVisible; }
    bool isAlwaysShowTrayIcon() const { return alwaysShowTrayIcon; }

    SelectionMode selectionMode() const;
    void setSelectionMode(SelectionMode mode);

    HorizontalHeaderFormat horizontalHeaderFormat() const;
    void setHorizontalHeaderFormat(HorizontalHeaderFormat format);
    QTextCharFormat headerTextFormat() const;
    void setHeaderTextFormat(const QTextCharFormat &format);
    QTextCharFormat weekdayTextFormat(Qt::DayOfWeek dayOfWeek) const;
    void setWeekdayTextFormat(Qt::DayOfWeek dayOfWeek, const QTextCharFormat &format);
    QMap<QDate, QTextCharFormat> dateTextFormat() const;
    QTextCharFormat dateTextFormat(const QDate &date) const;
    void setDateTextFormat(const QDate &date, const QTextCharFormat &format);

public slots:
    void update();
    void setSelectedDate(const QDate &date);
    void setDateRange(const QDate &min, const QDate &max);
    void setCurrentPage(int year, int month);
    void setGridVisible(bool show);
    void setNavigationBarVisible(bool visible);
    void setAlwaysShowTrayIcon(bool show);
    void showNextMonth();
    void showPrevMonth();
    void showNextYear();
    void showPrevYear();
    void showSelectedDate();
    void showToday();

signals:
    void selectionChanged();
    void clicked(const QDate &date);
    void activated(const QDate &date);
    void currentPageChanged(int year, int month);

protected:
    explicit CalendarWidget(QWidget *parent = 0);
    ~CalendarWidget();
    void changeEvent(QEvent *e);
    bool eventFilter(QObject *watched, QEvent *event);
    void showEvent(QShowEvent *event);
    void closeEvent(QCloseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void resizeEvent(QResizeEvent *event);
    void keyPressEvent(QKeyEvent *event);
//    void updateCell(const QDate &date);
//    void updateCells();

private:
    Ui::CalendarWidget *ui;

    CalendarModel *m_model;
    CalendarView *m_view;
    CalendarDelegate *m_delegate;
    QItemSelectionModel *m_selection;

    void createCtrls();
    void createActions();
    void createTrayIcon();
    void updateIcons();
    void updateMonthMenu();
    void updateMonthMenuNames();
    void updateNavigationBar();
    void updateCurrentPage(const QDate &newDate);
    QDate getCurrentDate();

    MenuButton *btnOptions;
    MenuButton *btnMonth;
    QSpinBox *sbYear;
    QMap<int, QAction *> monthToAction;
    QSystemTrayIcon *trayIcon;
    QMenu *trayIconMenu;
    Qt::FocusPolicy oldFocusPolicy;
    mutable QSize cachedSizeHint;
    Options *options;
    bool navBarVisible;
    bool alwaysShowTrayIcon;
    bool widgetMove;
    int diffX, diffY;

private slots:
    void showDate(const QDate &date);
    void changeDate(const QDate &date);
    void changeDate(const QDate &date, bool changeMonth);
    void editingFinished();
    void monthChanged(QAction *);
    void prevMonth();
    void nextMonth();
    void yearEditingFinished();
    void yearClicked();
    void trayActivated(QSystemTrayIcon::ActivationReason reason);
    void restoreWindow();
    void scaleChanged(QAction *act);
    void scaleChanged(Options::ScaleSize xScale);
    void applyOptions(Options::OptionMode optionMode);
    void contextMenuFinished();
};

#endif // CALENDARWIDGET_H
